package cn.iocoder.yudao.module.iot.service.room;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.room.vo.IotRoomPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.room.vo.IotRoomSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.room.IotRoomDO;
import cn.iocoder.yudao.module.iot.dal.mysql.room.IotRoomMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.ROOM_NOT_EXISTS;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.ROOM_NAME_EXISTS;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.ROOM_HAS_CHILDREN;

/**
 * IoT 房间 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class IotRoomServiceImpl implements IotRoomService {

    @Resource
    private IotRoomMapper roomMapper;

    @Override
    public Long createRoom(IotRoomSaveReqVO createReqVO) {
        // 校验房间名称在同一用户下是否唯一
        validateRoomNameUnique(createReqVO.getUserId(), createReqVO.getName(), null);
        
        // 如果有父级房间，校验父级房间是否存在
        if (createReqVO.getParentId() != null) {
            validateRoomExists(createReqVO.getParentId());
        }

        // 插入
        IotRoomDO room = BeanUtils.toBean(createReqVO, IotRoomDO.class);
        roomMapper.insert(room);
        return room.getId();
    }

    @Override
    public void updateRoom(IotRoomSaveReqVO updateReqVO) {
        // 校验存在
        validateRoomExists(updateReqVO.getId());
        
        // 校验房间名称在同一用户下是否唯一
        validateRoomNameUnique(updateReqVO.getUserId(), updateReqVO.getName(), updateReqVO.getId());
        
        // 如果有父级房间，校验父级房间是否存在
        if (updateReqVO.getParentId() != null) {
            validateRoomExists(updateReqVO.getParentId());
        }

        // 更新
        IotRoomDO updateObj = BeanUtils.toBean(updateReqVO, IotRoomDO.class);
        roomMapper.updateById(updateObj);
    }

    @Override
    public void deleteRoom(Long id) {
        // 校验存在
        validateRoomExists(id);
        
        // 校验是否有子房间
        List<IotRoomDO> children = roomMapper.selectListByParentId(id);
        if (!children.isEmpty()) {
            throw exception(ROOM_HAS_CHILDREN);
        }

        // 删除
        roomMapper.deleteById(id);
    }

    private void validateRoomNameUnique(Long userId, String name, Long id) {
        IotRoomDO room = roomMapper.selectByUserIdAndName(userId, name);
        if (room == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的房间
        if (id == null) {
            throw exception(ROOM_NAME_EXISTS);
        }
        if (!room.getId().equals(id)) {
            throw exception(ROOM_NAME_EXISTS);
        }
    }

    @Override
    public IotRoomDO getRoom(Long id) {
        return roomMapper.selectById(id);
    }

    @Override
    public PageResult<IotRoomDO> getRoomPage(IotRoomPageReqVO pageReqVO) {
        return roomMapper.selectPage(pageReqVO);
    }

    @Override
    public List<IotRoomDO> getRoomListByUserId(Long userId) {
        return roomMapper.selectListByUserId(userId);
    }

    @Override
    public List<IotRoomDO> getRoomListByParentId(Long parentId) {
        return roomMapper.selectListByParentId(parentId);
    }

    @Override
    public List<IotRoomDO> getRoomListByUserIdAndParentId(Long userId, Long parentId) {
        return roomMapper.selectListByUserIdAndParentId(userId, parentId);
    }

    @Override
    public void validateRoomExists(Long id) {
        if (roomMapper.selectById(id) == null) {
            throw exception(ROOM_NOT_EXISTS);
        }
    }

    @Override
    public void validateRoomExists(Collection<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        // 获得房间信息
        List<IotRoomDO> rooms = roomMapper.selectBatchIds(ids);
        if (rooms.size() != ids.size()) {
            throw exception(ROOM_NOT_EXISTS);
        }
    }

}
